Skip to main content

平台 CLI 教程

本教程将引导您使用平台 CLI 构建、测试并将示例应用推送到 Zapier。我们将使用一个模拟 API 来处理食谱示例,但对于生产环境的 Zapier 应用,您应连接到真实的 API。

先决条件

# 全局安装 CLI
npm install -g zapier-platform-cli

要查看平台 CLI 中所有可用命令,请运行 zapier help

  • 接下来,通过 CLI 进行身份验证。
# 使用部署密钥设置对 Zapier 平台的身份验证
zapier login

Zapier 会将您的部署密钥写入 ~/.zapierrc 文件。请妥善保管该文件,不要将其纳入源代码管理。

1. 开始一个集成

使用 init 命令设置 所需的结构。系统会显示可用模板列表供您选择。

# 创建一个目录,其中包含最小所需的文件,并选择一个模板
zapier init example-app --template minimal
# 进入新目录
cd example-app

在该目录中,您会看到几个文件。package.json 是典型 Node.js 应用的依赖文件,已预填充了一些依赖项,其中最重要的是 zapier-platform-core,这是使您的应用与 Zapier 平台兼容的核心。还有一个 index.js 文件和一个测试目录(稍后详述)。在继续之前,请安装应用的依赖项:

npm install

index.js

index.js 是您的应用的入口点。这是平台用于理解您的应用如何与 Zapier 交互的地方。在您选择的代码编辑器中打开该目录。

您可能会在 index.js 中看到以下内容:

  • 一个单一的 module.exports 定义,由 Zapier 解释。

  • triggers 用于描述从您的应用数据中触发的机制。

  • searches 用于描述在您的应用中查找数据的方式。

  • creates 用于描述在您的应用中创建数据的方式。

  • resources 是可选的,用于方便描述应用中的 CRUD-like 对象(请参阅 示例 resources 应用)。

  • beforeRequestafterResponse 是 HTTP 客户端的钩子,用于在每次调用中操作请求和响应。

2. 添加一个触发器

添加一个 触发器,配置为从模拟 API 中读取数据:

zapier scaffold trigger recipe

scaffold 会创建一个新文件 recipe.js,位于 triggers 文件夹中。在构建自己的集成时,您可能会使用如 contact.jslead.jsorder.js 这样的文件名。

打开 triggers/recipe.js(由 zapier scaffold trigger recipe 创建的文件),并用以下内容替换:

const listRecipes = async (z, bundle) => {
const response = await z.request("http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes");
return response.data;
};

module.exports = {
key: "recipe",
noun: "Recipe",
display: {
label: "New Recipe",
description: "Triggers when a new recipe is created.",
},
operation: {
perform: listRecipes,
sample: {
id: 1,
createdAt: 1472069465,
name: "Best Spaghetti Ever",
authorId: 1,
directions: "1. Boil Noodles\n2. Serve with sauce",
style: "italian",
},
},
};

要本地测试触发器,请运行 zapier invoke。该命令会询问您要调用的操作。目前我们只有一个触发器 recipe,因此可以选择它。

$ zapier invoke
? Which action type would you like to invoke? trigger
? Which "trigger" key would you like to invoke? recipe
✔ Invoking triggers.recipe.operation.inputFields
✔ Invoking triggers.recipe.operation.perform
[
{
"id": "1",
"createdAt": 1471984289,
"name": "name 1",
"authorId": 63,
"directions": "directions 1",
"style": "style 1"
},
<omitted...>
]

回顾代码:listRecipes 函数负责 API 操作,包括发出 HTTP 请求并返回解析后的响应数据。

在 JavaScript 中,async/await 是基于 Promises 的语法糖。请确保在调用异步函数时使用 await.then()

listRecipes 函数接收两个参数:z 对象和 bundle 对象。

  • Z 对象 是一组处理 API 的实用工具。在示例中,我们使用 z.request 发出 HTTP 调用。

  • Bundle 对象 包含 API 调用所需的数据,如身份验证凭证或 POST 正文数据。在示例中,未使用 Bundle,因为简单 GET 请求不需要这些。

虽然可以使用其他 Node.js 库实现相同功能,但推荐使用 z 对象,因为这些工具内置了增强 Zapier 体验的功能,如 HTTP 调用日志和错误处理。

module.exports 中,我们导出了元数据、listRecipes 函数和样本。Zapier 会使用这些元数据将其暴露给用户。

此外,scaffold 命令还执行了以下操作:

index.js 文件现在包括:

const getRecipe = require('./triggers/recipe');
module.exports = {
// ...
triggers: {
[getRecipe.key]: getRecipe,
},
// ...
};

在 test/triggers 文件夹中,创建了 recipe.test.js 文件:

const App = require("../../index");
const appTester = zapier.createAppTester(App);
// 如果可用,将 .env 文件加载到环境中
zapier.tools.env.inject();

describe("triggers.recipe", () => {
it("should run", async () => {
const bundle = {
inputData: {}
};
const results = await appTester(App.triggers.recipe.operation.perform, bundle);
expect(results).toBeDefined();
// TODO: add more assertions
});
});

运行 zapier test 应能通过测试:

$ zapier test
Validating project locally
No structural errors found during validation routine. This project is structurally sound!
✔ Running integration checks...
23 checks passed
Integration checks passed, no issues found.
Adding /Users/marinahand/.zapierrc to environment as ZAPIER_DEPLOY_KEY...
Running test suite with the following command: npm run --silent test --
PASS test/triggers/recipe.test.js
PASS test/triggers.test.js
(7.52s)
Test Suites: 2 passed, 2 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 9.429s
Ran all test suites.

本示例仅使用一个测试,但您可以在 另一个示例应用 中查看多个测试。

3. 修改一个触发器

要让用户自定义触发的食谱菜式风格,请添加一个输入字段。

triggers/recipe.js 中,用以下内容替换文件:

const listRecipes = async (z, bundle) => {
const params = {};
if (bundle.inputData.style) {
params.style = bundle.inputData.style;
}
const requestOptions = {
url: "http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes",
params: params,
};
const response = await z.request(requestOptions);
return response.data;
};

module.exports = {
key: "recipe",
noun: "Recipe",
display: {
label: "New Recipe",
description: "Triggers when a new recipe is created.",
},
operation: {
inputFields: [
{
key: "style",
type: "string",
helpText: "Which styles of cuisine this should trigger on.",
required: false,
},
],
perform: listRecipes,
sample: {
id: 1,
createdAt: 1472069465,
name: "Best Spagetti Ever",
authorId: 1,
directions: "1. Boil Noodles\n2. Serve with sauce",
style: "italian",
},
outputFields: [
{ key: "id", label: "ID" },
{ key: "createdAt", label: "Created At" },
{ key: "name", label: "Name" },
{ key: "directions", label: "Directions" },
{ key: "authorId", label: "Author ID" },
{ key: "style", label: "Style" },
],
},
};

输入字段键 "style" 已添加到:

  • operation 中的 inputFields - 定义在 Zap 编辑器中显示的字段,该字段非必填。

  • listRecipes 函数中 - 使用 bundle.inputData.style 提供的风格。

在本地开发中,重新运行 zapier invoke 以验证。指定参数:

$ zapier invoke trigger recipe --inputData '{"style":"style 20"}'
✔ Invoking triggers.recipe.operation.inputFields
✔ Invoking triggers.recipe.operation.perform
[
{
"id": "20",
"createdAt": 1578590011,
"name": "name 20",
"authorId": 90,
"directions": "directions 20",
"style": "style 20"
}
]

调整测试:在 test/triggers 中,替换 recipe.test.js 文件:

const zapier = require("zapier-platform-core");
const App = require("../../index");
const appTester = zapier.createAppTester(App);

describe("triggers", () => {
describe("new recipe trigger", () => {
it("should load recipes", async () => {
const bundle = {
inputData: {
style: "style 2",
},
};
const results = await appTester(App.triggers.recipe.operation.perform, bundle);
expect(results.length).toBeGreaterThan(1);
const firstRecipe = results[0];
expect(firstRecipe.name).toEqual("name 2");
expect(firstRecipe.directions).toEqual("directions 2");
});
it("should load recipes without filters", async () => {
const bundle = {};
const results = await appTester(App.triggers.recipe.operation.perform, bundle);
expect(results.length).toBeGreaterThan(1);
const firstRecipe = results[0];
expect(firstRecipe.name).toEqual("name 1");
expect(firstRecipe.directions).toEqual("directions 1");
});
});
});

运行测试以确认:

zapier test

4. 部署一个集成

将本地应用推送到 Zapier,以便在 Zap 中使用。

您可以管理多个版本,以简化更改和测试。首先推送一个版本。

首次推送时,需要注册应用。运行 zapier register 并提供详细信息,然后使用 zapier push 推送:

$ zapier push
✔ Copying project to temp directory
✔ Installing project dependencies
✔ Applying entry point file
✔ Building app definition.json
✔ Validating project schema and style
✔ Zipping project and dependencies
✔ Testing build
✔ Cleaning up temp directory
✔ Uploading version 1.0.0
Push complete! Built build/build.zip and build/source.zip and uploaded them to Zapier.

登录 Zap 编辑器 创建 Zap。

在触发器步骤中,选择您的应用和“New Recipe”触发器,您会看到定义的标签和描述。

在编辑器中填写“style”字段,运行测试时,listRecipes 函数会执行 API 请求。

查看日志:

$ zapier logs --type http
The logs of your app "Example App" listed below.
┌────────┬────────┬────────────────────────────────────────────────────────┬───────────────┬─────────┬──────────────────────────────────────┬───────────────────────────┐
│ Status │ Method │ URL │ Querystring │ Version │ Step │ Timestamp │
├────────┼────────┼────────────────────────────────────────────────────────┼───────────────┼─────────┼──────────────────────────────────────┼───────────────────────────┤
│ 200 │ GET │ http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes │ style=italian │ 1.0.0 │ a9055e16-fc0d-4fb2-a3e6-9d442d1f70e8 │ 2016-09-13T15:11:30-05:00 │
└────────┴────────┴────────────────────────────────────────────────────────┴───────────────┴─────────┴──────────────────────────────────────┴───────────────────────────┘
Most recent logs near the bottom.

5. 添加身份验证

身份验证对 API 交互至关重要。Zapier 支持多种 方案。本例中,在标头中包含 API 密钥。

示例应用:

  • Session Auth
  • Digest Auth

index.js 中,向 module.exports 添加:

authentication: {
type: 'custom',
fields: [
{
key: 'apiKey',
type: 'string'
}
],
test: async (z, bundle) => {
const response = await z.request('http://57b20fb546b57d1100a3c405.mockapi.io/api/me');
return response.data;
},
},

定义了:

  • fields:定义身份验证字段,类似于触发器的 inputFields

  • test:验证凭证的函数。

index.js 中添加辅助函数:

const addApiKeyToHeader = (request, z, bundle) => {
request.headers["My-Auth-Header"] = bundle.authData.apiKey;
return request;
};

并在 module.exports 中添加:

beforeRequest: [
addApiKeyToHeader,
],

测试身份验证:

$ zapier invoke auth start
The .env file does not exist or is empty. You may need to set some environment variables in there if your code uses process.env.
? apiKey | string: mock-api-key
Auth data appended to .env file. Run `zapier invoke auth test` to test it.

$ zapier invoke auth test
✔ Invoking authentication.test
[
{
"id": "1",
"createdAt": 1473801403,
"userName": "userName 1"
}
]

推送更新:

zapier push

在 Zap 中添加帐户并验证日志。

6. 邀请团队成员

共享集成至 开发人员仪表板

运行:

  • zapier team:add user@example.com admin

  • zapier team:add user@example.com collaborator

7. 与用户共享

运行 zapier users:add user@example.com 1.0.0

或者使用链接:运行 zapier users:links

8. 修改集成

在新版本中进行更改。

了解更多

需要帮助?联系我们